package com.biubiu.firefly.wallpaper.box;

import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Handler;
import android.service.wallpaper.WallpaperService;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.SurfaceHolder;

import com.biubiu.firefly.Constant;
import com.biubiu.firefly.R;

import org.jbox2d.callbacks.ContactImpulse;
import org.jbox2d.callbacks.ContactListener;
import org.jbox2d.collision.Manifold;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.World;
import org.jbox2d.dynamics.contacts.Contact;

import java.util.ArrayList;
import java.util.Random;

public class BoxWallpaperService extends WallpaperService {

    private MyEngine myEngine;

    @Override
    public Engine onCreateEngine() {
        myEngine = new MyEngine(this);
        return myEngine;
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        // 当配置（如屏幕方向）改变时，更新你的渲染逻辑
        boolean isLandscape = newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE;
        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
            // 横屏
        } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
            // 竖屏
        }
        Log.d("liaoyucheng","isLandscape = "+isLandscape);
        myEngine.makeEventSpace();
    }

    class MyEngine extends  Engine implements SensorEventListener{
        private final Context mContext;
        private final Handler mHandler = new Handler();
        private Paint paint;
        private WorldFeatures mWorldFeatures = WorldFeatures.getWorldFeatures();

        private long lastTime;
        private World world;
        private final Random random = new Random();
        //物体列表
        private final ArrayList<MyBody> bodyList =new ArrayList<>();
        private Sensor sensorGravity; //重力传感器
        private Sensor sensorAccelerometer; //加速度传感器
        private SensorManager sensorManager;


        public MyEngine(Context context) {
            this.mContext = context;
        }

        private final Runnable mRunnable = new Runnable() {
            @Override
            public void run() {
                mHandler.removeCallbacks(mRunnable);
                drawShapeDrawable();
                mHandler.postDelayed(mRunnable,5);
            }
        };

        private void drawShapeDrawable() {
            world.step(Constant.TIME_STEP, Constant.VELOCITY, Constant.ITERATE);
            SurfaceHolder holder = getSurfaceHolder();
            Canvas canvas = holder.lockCanvas();
            try {
                synchronized(holder){
                    onDraw(canvas);
                }
            } catch(Exception e){
                e.printStackTrace();
            } finally {
                holder.unlockCanvasAndPost(canvas);
            }
        }

        private void onDraw(Canvas canvas){
            if(canvas==null) {
                return ;
            }
            canvas.drawColor(getResources().getColor(R.color.cyan_dark));//背景色
            //canvas.drawARGB(255, 255, 255, 255); //设置背景颜色白色
            for (MyBody mb : bodyList) {
                mb.drawSelf(canvas, paint);
            }
        }

        @Override
        public void onCreate(SurfaceHolder surfaceHolder) {
            super.onCreate(surfaceHolder);
            //重力传感器
            sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
            sensorGravity = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
            sensorAccelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);

            paint =new Paint();
            paint.setAntiAlias(true);

            Vec2 gravity = new Vec2(0.0f,0.0f);
            //创建世界
            world = new World(gravity);
            world.setContactListener(new ContactListener() {
                @Override
                public void beginContact(Contact contact) {
                    // 碰撞时调用
                }

                @Override
                public void endContact(Contact contact) {
                    // 碰撞结束时调用
                }

                @Override
                public void preSolve(Contact contact, Manifold oldManifold) {
                    // 碰撞前调用
                }

                @Override
                public void postSolve(Contact contact, ContactImpulse impulse) {
                    // 碰撞后调用
                }
            });

            makeEventSpace();
        }

        public void makeEventSpace() {
            //移除所有物体,重新生成
            if(!bodyList.isEmpty()){
                for(MyBody body: bodyList){
                    world.destroyBody(body.body);
                }
                bodyList.clear();
            }
            //获取屏幕尺寸
            DisplayMetrics dm = mContext.getResources().getDisplayMetrics();
            int widthPixels;
            int heightPixels;
            if(dm.widthPixels<dm.heightPixels)
            {
                widthPixels=dm.widthPixels;
                heightPixels=dm.heightPixels;
            }
            else
            {
                widthPixels=dm.heightPixels;
                heightPixels=dm.widthPixels;
            }
            Box2DUtil.INSTANCE.initEdges(widthPixels, heightPixels, world);

            //气泡数量
            int count = mWorldFeatures.stickers.size();
            for(int i = 0; i< count; i++){
                int d = -1;
                if(i%2==0){
                    d = 1;
                }
                // 生成一个随机浮点数
                float radius = mWorldFeatures.radius;
                if(mWorldFeatures.randomRadius){
                    float randomNumber = 0.5f + random.nextFloat() / 2f;
                    radius = (heightPixels- count *5f)/ count / 2f * randomNumber;
                }
                Log.d("liaoyucheng","radius = "+radius);

                //精确缩放到指定大小
                Bitmap thumbImg = Bitmap.createScaledBitmap(mWorldFeatures.stickers.get(i),
                        (int) (radius*2.0f), (int) (radius*2.0f), true);
                MyCircleColor box = Box2DUtil.INSTANCE.createBody(
                        widthPixels/ count *i,
                        heightPixels/ count *i + radius,
                        50*(i+1) * d,
                        250*(count - i) * d,
                        radius,
                        world,
                        ColorUtil.getColor(Math.abs(random.nextInt())),
                        thumbImg
                );
                bodyList.add(box);
            }
        }


        @Override
        public void onVisibilityChanged(boolean visible) {
            super.onVisibilityChanged(visible);
            if (visible) {
                mHandler.post(mRunnable);
                if(mWorldFeatures.gravity > 0){
                    sensorManager.registerListener(this, sensorGravity, SensorManager.SENSOR_DELAY_NORMAL);
                    sensorManager.registerListener(this, sensorAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
                }
            } else {
                if(mWorldFeatures.gravity > 0){
                    sensorManager.unregisterListener(this, sensorGravity);
                    sensorManager.unregisterListener(this, sensorAccelerometer);
                }
                mHandler.removeCallbacks(mRunnable);
            }
        }

        //获取SurfaceHolder时调用
        @Override
        public SurfaceHolder getSurfaceHolder() {
            return super.getSurfaceHolder();
        }

        //手势移动时回调，onOffsetsChanged要注意一下，还记得有的手机滑动桌面时候背景图片会跟着左右移动吗，
        // 这个方法就可以实现这个效果，在手势滑动的每一帧都会回调依次。
        /**
         * @param xOffset      x方向滑动的百分比（与桌面分页数有关）
         * @param yOffset      y方向滑动百分比（一般用不到）
         * @param xOffsetStep  x方向每个分页所占的百分比（1 / xOffsetStep = 桌面的分页数）
         * @param yOffsetStep  同理
         * @param xPixelOffset x放下像素偏移量
         * @param yPixelOffset 同理
         */
        @Override
        public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep, float yOffsetStep, int xPixelOffset, int yPixelOffset) {
            super.onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep, xPixelOffset, yPixelOffset);
        }

        //Surface创建时回调
        @Override
        public void onSurfaceCreated(SurfaceHolder holder) {
            super.onSurfaceCreated(holder);
        }

        //Surface销毁时回调
        @Override
        public void onSurfaceDestroyed(SurfaceHolder holder) {
            super.onSurfaceDestroyed(holder);
        }

        @Override
        public void onDestroy() {
            super.onDestroy();
            mHandler.removeCallbacks(mRunnable);
        }

        @Override
        public void onSensorChanged(SensorEvent event) {
            if (event.sensor.getType() == Sensor.TYPE_GRAVITY) {
                float x = event.values[0] * (mWorldFeatures.gravity / 10f);
                float y = event.values[1] * (mWorldFeatures.gravity / 10f);
                float z = event.values[2] * (mWorldFeatures.gravity / 10f);
                //Log.d("liaoyucheng","x = "+x+",y = "+y+",z = "+z);
                // 计算倾斜角度示例
                //double inclination = Math.atan2(Math.sqrt(x * x + y * y), z) * (180 / Math.PI);
                // 此处可使用inclination值进行进一步的处理，如游戏控制等

                try {
                    world.setGravity(new Vec2(-x,y));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }else if (event.sensor.getType() == Sensor.TYPE_LINEAR_ACCELERATION) {
                float x = event.values[0];
                float y = event.values[1];
                float z = event.values[2];

                if(Math.abs(x) > Constant.ACCELERATION || Math.abs(y) > Constant.ACCELERATION || Math.abs(z) > Constant.ACCELERATION){
                    if(System.currentTimeMillis() - lastTime < 1000){
                        return;
                    }
                    lastTime = System.currentTimeMillis();
                    if(Math.abs(x) < Constant.ACCELERATION){
                        x = 0f;
                    }
                    if(Math.abs(y) < Constant.ACCELERATION){
                        y = 0f;
                    }
                    if(Math.abs(z) < Constant.ACCELERATION){
                        z = 0f;
                    }
                    //Log.d("liaoyucheng","x = "+x+",y = "+y+",z = "+z);
                    try {
                        //world.setGravity(new Vec2(-x,y));
                        for(MyBody body: bodyList){
                            if(body instanceof MyCircleColor){
                                body.body.setLinearVelocity(
                                        new Vec2(
                                                Box2DUtil.INSTANCE.switchPositionToView(-x),
                                                Box2DUtil.INSTANCE.switchPositionToView(y)
                                        )
                                );
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

            }
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {

        }
    }
}
